
#include "stdafx.h"
#include "Win32.DateTime.h"
#include "Win32.Number.h"
#include <time.h>

// -----------------------------------------------------------------------------

namespace Kif
{
namespace Win32
{

void TIMESTAMP_STRUCT::Now()
{
   time_t nsecs ;
   struct tm loctime ;
   nsecs = ::time((time_t*)0) ;
   localtime_s(&loctime,&nsecs) ;

   Year   = loctime.tm_year+1900 ;
   Month  = loctime.tm_mon+1 ;
   Day    = loctime.tm_mday ;
   Hour   = loctime.tm_hour ;
   Minute = loctime.tm_min ;
   Second = loctime.tm_sec ;
   Fraction = 0;
}

Kif::Win32::String *DateTime::GetYmdHmsString(
   DateTime *dateTime,
   short dayLength,  TCHAR daySeparator,
   short timeLength, TCHAR timeSeparator, bool separated)
{
   SYSTEMTIME dtime ;

   dtime.wYear   = dateTime->Year;
   dtime.wMonth  = dateTime->Month;
   dtime.wDay    = dateTime->Day;
   dtime.wHour   = dateTime->Hour;
   dtime.wMinute = dateTime->Minute;
   dtime.wSecond = dateTime->Second;

   // validate string lengths
   if (dayLength > 0)
   {
      if (dayLength > MaxYmdStringLength)
         dayLength = MaxYmdStringLength;
      if (dayLength < MinYmdStringLength)
         dayLength = MinYmdStringLength;
   }

   if (timeLength > 0)
   {
      if (timeLength > MaxHmsStringLength)
         timeLength = MaxHmsStringLength;
      if (timeLength < MinHmsStringLength)
         timeLength = MinHmsStringLength;
   }

   // prepare output string / buffer
   short length = dayLength + timeLength + (separated?1:0);
   Kif::Win32::String *s = new Kif::Win32::String();
   s->AllocBuffer(length+1);
   TCHAR *os = s->GetBuffer();

   if (dayLength > 0)
   {

      // prepare date string based on length
      Kif::Win32::String y,M,d;

      Kif::Win32::Number::ToString(M,dtime.wMonth);
      Kif::Win32::Number::ToString(d,dtime.wDay);
      Kif::Win32::Number::ToString(y,dtime.wYear);

      TCHAR *ys = y.GetBuffer(), *Ms = M.GetBuffer(), *ds = d.GetBuffer();

      // prepare year without century
      if (dayLength == MinYmdStringLength)
         ys += 2;

      // write year to output
      while (*ys)
      {
         *os = *ys;
         os++;
         ys++;
      }

      // write separator
      if (daySeparator != 0)
      {
         *os = daySeparator;
         os++;
      }

      // write month
      if (*(Ms+1) == NULL)
      {
         *os = '0';
         os++;
      }
      while (*Ms)
      {
         *os = *Ms;
         os++;
         Ms++;
      }

      // write separator
      if (daySeparator != 0)
      {
         *os = daySeparator;
         os++;
      }

      // write day
      if (*(ds+1) == NULL)
      {
         *os = '0';
         os++;
      }
      while (*ds)
      {
         *os = *ds;
         os++;
         ds++;
      }
   }

   if (timeLength > 0)
   {
      // prepare the time string based on length
      Kif::Win32::String h,m,n;

      Kif::Win32::Number::ToString(h,dtime.wHour),
      Kif::Win32::Number::ToString(m,dtime.wMinute),
      Kif::Win32::Number::ToString(n,dtime.wSecond);

      TCHAR *hs = h.GetBuffer(), *ms = m.GetBuffer(), *ns = n.GetBuffer();

      // write separator
      if (separated != 0)
      {
         *os = ' ';
         os++;
      }

      // write hour
      if (*(hs+1) == NULL)
      {
         *os = '0';
         os++;
      }
      while (*hs)
      {
         *os = *hs;
         os++;
         hs++;
      }

      // write separator
      if (timeSeparator != 0)
      {
         *os = timeSeparator;
         os++;
      }

      // write hour
      if (*(ms+1) == NULL)
      {
         *os = '0';
         os++;
      }
      while (*ms)
      {
         *os = *ms;
         os++;
         ms++;
      }

      // write separator
      if (timeSeparator != 0)
      {
         *os = timeSeparator;
         os++;
      }

      // write hour
      if (*(ns+1) == NULL)
      {
         *os = '0';
         os++;
      }
      while (*ns)
      {
         *os = *ns;
         os++;
         ns++;
      }
   }

   *os = NULL;  // null terminate string
   s->length = os - s->GetBuffer();
   return(s);
}  // end of GetYmdHmsString string

DateTime *DateTime::CCYYMMDD_ToDate(TCHAR *string)
{
   DateTime *dt = new DateTime();
   if (dt == NULL)
      return(NULL);

   TCHAR y[5];
   TCHAR m[3];
   TCHAR d[3];

   y[4] = m[2] = d[2] = NULL;
   y[0] = string[0];
   y[1] = string[1];
   y[2] = string[2];
   y[3] = string[3];
   m[0] = string[4];
   m[1] = string[5];
   d[0] = string[6];
   d[1] = string[7];

   dt->Year  = (short)Kif::Win32::Number::ToLong(y);
   dt->Month = (short)Kif::Win32::Number::ToLong(m);
   dt->Day   = (short)Kif::Win32::Number::ToLong(d);

   dt->Hour     = 0;
   dt->Minute   = 0;
   dt->Second   = 0;
   dt->Fraction = 0;

   return(dt);
}  // end of CCYYMMDD_ToDate

DateTime *DateTime::MMDDCCYY_ToDate(TCHAR *string)
{
   DateTime *dt = new DateTime();
   if (dt == NULL)
      return(NULL);

   TCHAR y[5];
   TCHAR m[3];
   TCHAR d[3];

   y[4] = m[2] = d[2] = NULL;
   m[0] = string[0];
   m[1] = string[1];
   d[0] = string[2];
   d[1] = string[3];
   y[0] = string[4];
   y[1] = string[5];
   y[2] = string[6];
   y[3] = string[7];

   dt->Year  = (short)Kif::Win32::Number::ToLong(y);
   dt->Month = (short)Kif::Win32::Number::ToLong(m);
   dt->Day   = (short)Kif::Win32::Number::ToLong(d);

   dt->Hour     = 0;
   dt->Minute   = 0;
   dt->Second   = 0;
   dt->Fraction = 0;

   return(dt);
}  // end of MMDDCCYY_ToDate

// -----------------------------------------------------------------------------

#define DD_MMM_YYYY_Len 11
#define DD_MMM_YY_Len 9

DateTime *DateTime::DD_MMM_YYYY_ToDate(Kif::Win32::String &string)
{
   // make sure that format is DD_MMM_YYYY (len=11) or DD_MMM_YY (len=9)
   size_t len = string.GetLength();
   if ((len != DD_MMM_YYYY_Len) && (len != DD_MMM_YY_Len))
      return(NULL);

   // parse string...
   DateTime *dt = new DateTime();
   if (dt == NULL)
      return(NULL);

   TCHAR *b = string.GetBuffer();
   TCHAR y[5];
   TCHAR m[4];
   TCHAR d[3];

   y[4] = m[3] = d[2] = NULL;

   d[0] = b[0];
   d[1] = b[1];
   m[0] = b[3];
   m[1] = b[4];
   m[2] = b[5];

   if (len == DD_MMM_YYYY_Len)
   {
      y[0] = b[7];
      y[1] = b[8];
      y[2] = b[9];
      y[3] = b[10];
   }
   else
   {
      y[0] = '2';
      y[1] = '0';
      y[2] = b[7];
      y[3] = b[8];
   }

   switch(m[0])
   {
      case 'J':
         if (m[1] == 'A')
         {
            m[0] = '0';   // JAN
            m[1] = '1';
         }
         else
         if (m[2] == 'L')
         {
            m[0] = '0';   // JUL
            m[1] = '7';
         }
         else
         {
            m[0] = '0';   // JUN
            m[1] = '6';
         }
         break;
      case 'F':
         m[0] = '0';      // FEB
         m[1] = '2';
         break;
      case 'M':
         if (m[2] == 'R')
         {
            m[0] = '0';   // MAR
            m[1] = '3';
         }
         else
         {
            m[0] = '0';   // MAY
            m[1] = '5';
         }
         break;
      case 'A':
         if (m[2] == 'R')
         {
            m[0] = '0';   // APR
            m[1] = '4';
         }
         else
         {
            m[0] = '0';   // AUG
            m[1] = '8';
         }
         break;
      case 'S':
         m[0] = '0';      // SEP
         m[1] = '9';
         break;
      case 'O':
         m[0] = '1';      // OCT
         m[1] = '0';
         break;
      case 'N':
         m[0] = '1';      // NOV
         m[1] = '1';
         break;
      case 'D':
         m[0] = '1';      // DIC
         m[1] = '2';
         break;
   }
   m[2] = NULL;

   dt->Year  = (short)Kif::Win32::Number::ToLong(y);
   dt->Month = (short)Kif::Win32::Number::ToLong(m);
   dt->Day   = (short)Kif::Win32::Number::ToLong(d);

   if (len == DD_MMM_YY_Len)  // take care of century issue for YY dates
   {
      DateTime ndt;
      ndt.Now();
      if (dt->Year > ndt.Year)
      {
         y[0] = '1';
         y[1] = '9';
         y[2] = b[7];
         y[3] = b[8];
         dt->Year = (short)Kif::Win32::Number::ToLong(y);
      }
   }

   dt->Hour     = 0;
   dt->Minute   = 0;
   dt->Second   = 0;
   dt->Fraction = 0;

   return(dt);
}  // end of DD_MMM_YYYY_ToDate

// -----------------------------------------------------------------------------

double TimeSpan::ToMilliseconds(DateTime &endTime, DateTime &startTime)
{
   return 0;
}  // end of ToMilliseconds

}  // end of Kif::Win32
}  // end of Kif

